<?php

namespace App\Service;

use App\Model\User;
use App\Model\UsersLive;
use App\Model\UsersOpenId;
use GuzzleHttp\Client;


class WechatService
{
    protected $client;
    protected $appId;
    protected $appSecret;
    protected $accessToken;

    public function __construct($appId, $appSecret)
    {
        $this->appId     = $appId;
        $this->appSecret = $appSecret;
        $this->client    = new Client();
        $this->getAccessToken();
    }

    /**
     * 获取Redis连接
     *
     * @return mixed|\Redis
     */
    private function redis()
    {
        return redis();
    }

    public function forceRefreshToken()
    {
        $accessToken = $this->refreshToken();

        if (empty($accessToken))
            for ($i = 0; $i < 3; $i++) {
                sleep($i * $i * $i);
                $accessToken = $this->refreshToken();
                if (!empty($accessToken)) {
                    break;
                }
            }
        $this->redis()->set('WX_ACCESS_TOKEN_' . $this->appId, $accessToken, 7100);
    }


    /**
     * 获取用户openid信息
     * @param $code
     * @return mixed
     */
    public function getOAuth($code)
    {
        $uri = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$this->appId}&" .
            "secret={$this->appSecret}&code={$code}&grant_type=authorization_code";

        $response = $this->client->request('GET', $uri);
        $content  = $response->getBody()->getContents();
        info("获取微信用户信息返回值: {$content}", [$uri]);

        return json_decode($content);
    }

    public function xcxJsCode2Session($code)
    {
        $uri      = "https://api.weixin.qq.com/sns/jscode2session?appid=$this->appId&secret=$this->appSecret&js_code=$code&grant_type=authorization_code";
        $response = $this->client->request('GET', $uri);
        $content  = $response->getBody()->getContents();
        info("获取小程序用户信息返回值: {$content}");

        return json_decode($content);
    }

    /**
     * 刷新 access_token
     * @return mixed
     */
    public function refreshToken()
    {
        $uri    = 'https://api.weixin.qq.com/cgi-bin/token?';
        $params = [
            'grant_type' => 'client_credential',
            'appid'      => $this->appId,
            'secret'     => $this->appSecret,
        ];
        info("刷新微信接口 access_token 参数:", $params);

        $response = $this->client->request('GET', $uri . http_build_query($params));
        $content  = $response->getBody()->getContents();

        info("刷新微信接口 access_token 返回值: {$content}");

        $data = json_decode($content);

        return data_get($data, 'access_token');
    }

    /**
     * 获取access_token
     */
    protected function getAccessToken()
    {
        $this->accessToken = $this->redis()->get('WX_ACCESS_TOKEN_' . $this->appId);

        if (empty($this->accessToken)) {
            $this->accessToken = $this->refreshToken();
            $this->redis()->set('WX_ACCESS_TOKEN_' . $this->appId, $this->accessToken, 7100);
        }
    }

    public function openLogin($code)
    {
        $oauth = $this->getOAuth($code);
        $openid = data_get($oauth, 'openid', '');

        if (empty($openid)) {
            throw new \Exception('获取抖音openid失败', 604);
        }

        $openUser = UsersOpenId::where('app_id', '=', $this->appId)->where('open_id', '=', $openid)->first();

        if (!empty($openUser)) {
            $updata = [];
            if (data_get($openUser, 'user_id', 0) == 0) {
                $user = User::create([
                    'name' => str_random(10),
                    'password' => time(),
                    'api_token' => str_random(50),
                    'status'    => 0,
                ]);
                $login_type = 1;
                $updata['user_id'] = data_get($user, 'id');
            }
            if (!empty($updata)) {
                UsersOpenId::where('app_id', '=', $this->appId)->where('open_id', '=', $openid)->update($updata);
            }

            $user_id = data_get($openUser, 'user_id', '');
        } else {
            // 创建微信信息
            $user = User::create([
                'name' => str_random(10),
                'password' => time(),
                'api_token' => str_random(50),
                'status'    => 0,
            ]);
            $login_type = 1;
            $user_id = data_get($user, 'id', '');
            $data = [
                'app_id'  => $this->appId,
                'open_id' => $openid,
                'unionid' => '',
                'user_id' => $user_id,
            ];
            $openUser = UsersOpenId::create($data);
        }

        $ulive = UsersLive::where('user_id', '=', $user_id)
            ->first();
        if (empty($ulive)) {
            UsersLive::create([
                'user_id' => $user_id,
                'nickname' => str_random(10),
                'head_img' => '',
                'sex' => 0,
            ]);
        }
        $r = $this->snsUserInfo($openid, data_get($oauth, 'access_token', '') );
        $j = json_decode($r, true);
        $headImg = data_get($j, 'headimgurl', '');
        $nickname = data_get($j, 'nickname', '');
        $sex = data_get($j, 'sex', '');
        UsersLive::where('user_id', '=', $user_id)
            ->update([
                'head_img' => $headImg,
                'sex' => $sex,
                'nickname' => $nickname
            ]);
//        $user = User::where('id', $user_id)->first();


        return $openUser;
    }

    public function snsUserInfo($openId, $accessToken)
    {

        $uri      = "https://api.weixin.qq.com/sns/userinfo?access_token=$accessToken&openid=$openId";
        $response = $this->client->request('GET', $uri);
        $content  = $response->getBody()->getContents();
        info('sns获取用户信息', [$openId, $content]);
        return $content;
    }

//
}